
#ifndef RTREACTOREPOLL_H
#define RTREACTOREPOLL_H

#if !defined (RT_LINUX) && !defined (RT_ENABLE_EPOLL)
  #error ERROR: Supports epoll only on LINUX!
#endif // !RT_LINUX && !RT_ENABLE_EPOLL

#include "RtReactorBase.h"
#include "RtReactorNotifyPipe.h"

#ifdef RT_ENABLE_CALENDAR_TIMER
  #include "RtTimerQueueCalendar.h"
#endif // RT_ENABLE_CALENDAR_TIMER

#include <sys/epoll.h>

class CRtReactorEpoll : public CRtReactorBase 
{
public:
	CRtReactorEpoll();
	virtual ~CRtReactorEpoll();

	// interface IRtReactor
	virtual RtResult Open();

	virtual RtResult NotifyHandler(
		IRtEventHandler *aEh, 
		IRtEventHandler::MASK aMask);

	virtual RtResult RunEventLoop();

	virtual RtResult StopEventLoop();
	
	virtual RtResult Close();

	virtual RtResult RegisterHandler(
		IRtEventHandler *aEh, 
		IRtEventHandler::MASK aMask);

	virtual RtResult RemoveHandler(
		IRtEventHandler *aEh, 
		IRtEventHandler::MASK aMask = IRtEventHandler::ALL_EVENTS_MASK);

protected:
	virtual RtResult OnHandleRegister(RT_HANDLE aFd, 
		IRtEventHandler::MASK aMask, IRtEventHandler *aEh);
	virtual void OnHandleRemoved(RT_HANDLE aFd);

	RtResult DoEpollCtl_i(RT_HANDLE aFd, IRtEventHandler::MASK aMask, int aOperation);
	
protected:
	RT_HANDLE m_fdEpoll;
	struct epoll_event *m_pEvents;
	CRtReactorNotifyPipe m_Notify;
	int m_nEventsBeginIndex;
	int m_nEventsEndIndex;

#ifdef RT_ENABLE_CALENDAR_TIMER
	// interface IRtTimerQueue
	virtual RtResult ScheduleTimer(IRtTimerHandler *aTh, 
					  LPVOID aArg,
					  const CRtTimeValue &aInterval,
					  DWORD aCount);

	virtual RtResult CancelTimer(IRtTimerHandler *aTh);

	CRtTimerQueueCalendar m_CalendarTimer;
	DWORD m_dwWallTimerJiffies;
#endif // RT_ENABLE_CALENDAR_TIMER
};

#endif // !RTREACTOREPOLL_H
